import { Component } from 'react';
import statusCode from './statusCode';
import api from '../../config/httpApi';

const host = api.Host;

/**
 * fetch 网络请求的header，可自定义header 内容
 * @type {{Accept: string, Content-Type: string, accessToken: *}}
 */
let header = {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'User-Agent': 'RN_FIRE',
    'X-Auth-Token': 'urB1NkW0flPxZhwtjg89EuAhXOZhWh4cGK0DKe96',
}
/**
 * GET 请求时，拼接请求URL
 * @param url 请求URL
 * @param params 请求参数
 * @returns {*}
 */
const handleUrl = url => params => {
    if (params) {
        let paramsArray = []
        Object.keys(params).forEach(key => paramsArray.push(key + '=' + encodeURIComponent(params[key])))
        if (url.search(/\?/) === -1) {
            typeof (params) === 'object' ? url += '?' + paramsArray.join('&') : url
        } else {
            url += '&' + paramsArray.join('&')
        }
    }
    return url
}

/**
 * fetch 网络请求超时处理
 * @param original_promise 原始的fetch
 * @param timeout 超时时间 40s
 * @returns {Promise.<*>}
 */
const timeoutFetch = (originalFetch, timeout = 40000) => {
    let timeoutBlock = () => { }
    let timeoutPromise = new Promise((resolve, reject) => {
        timeoutBlock = () => {
            // 请求超时处理
            reject('timeout promise')
        }
    })
    // Promise.race(iterable)方法返回一个promise
    // 这个promise在iterable中的任意一个promise被解决或拒绝后，立刻以相同的解决值被解决或以相同的拒绝原因被拒绝。
    let abortablePromise = Promise.race([
        originalFetch,
        timeoutPromise
    ])
    // console.log('abortable_promise >> ')
    // console.log(abortablePromise)
    setTimeout(() => {
        timeoutBlock()
    }, timeout)
    return abortablePromise
}

/**
 * 基于fetch 封装的GET 网络请求
 * @param url 请求URL
 * @param params 请求参数
 * @returns {Promise}
 */
const getRequest = (url, params = {}) => {
    return timeoutFetch(fetch(handleUrl(url)(params), {
        method: 'GET',
        credentials: 'include',
        headers: header
    }))
        .then((response) => {
            console.log(url, params, response)
            if (response.ok) {
                return response.json()
            } else {
                throw statusCode[response.status]
            }
        })
        .then((response) => {
            return response
        })
        .catch((error) => {
            console.log(error)
            throw error
        })
}

/**
 * 基于fetch 的 POST 请求
 * @param url 请求的URL
 * @param params 请求参数
 * @returns {Promise}
 */
const postRequest = (url, params = {}) => {
    let body = JSON.stringify(params)
    return timeoutFetch(fetch(url, {
        method: 'POST',
        credentials: 'include',
        headers: header,
        body
    }))
        .then((response) => {
            console.log(url, params, response)
            if (response.ok) { // 请求成功200
                return response.json()
            } else {
                throw statusCode[response.status]
            }
        })
        .then((response) => {
            return { ...response, params }
        })
        .catch((error) => {
            console.log('网络异常 >> ' + error)
            throw error
        })
}

/**
 * 基于fetch 的 formData上传
 * @param url 请求的URL
 * @param params 请求参数
 * @returns {Promise}
 */
const postFormDataRequest = (url, params = {}) => {
    return timeoutFetch(fetch(url, {
        method: 'POST',
        credentials: 'include',
        headers: {
            'Content-Type': 'multipart/form-data',
        },
        body: params
    }))
        .then((response) => {
            console.log(url, params, response)
            if (response.ok) { // 请求成功200
                return response.json()
            } else {
                throw statusCode[response.status]
            }
        })
        .then((response) => {
            return { ...response, params }
        })
        .catch((error) => {
            console.log(url, error)
            throw error
        })
}


export default class HttpUtils extends Component {

    /**
     * 封装get网络请求
     * @param url 请求的URL
     * @param params 请求参数
     * @returns {Promise}
     */
    static getFetch = (url, params) => {
        if (!url.startsWith('http')) {
            url = `${host}${url}`
        }
        return getRequest(url, params)
    }

    /**
     * 封装post网络请求
     * @param url 请求的URL
     * @param params 请求参数
     * @returns {Promise}
     */
    static postFetch = (url, params) => {
        if (!url.startsWith('http')) {
            url = `${host}${url}`
        }
        return postRequest(url, params)
    }

    /**
     * 封装post网络请求
     * @param url 请求的URL
     * @param params 请求参数
     * @returns {Promise}
     */
    static formDataFetch = (url, params) => {
        if (!url.startsWith('http')) {
            url = `${host}${url}`
        }
        return postFormDataRequest(url, params)
    }

    static get = (url, params) => {
        return getRequest(url, params)
    }
}